//-----------------------------------------------------------------------------
/**
 * The static class that handles input data from the mouse and touchscreen.
 *
 * @class TouchInput
 */
export class TouchInput {
    static keyRepeatWait = 24;
    static keyRepeatInterval = 6;

    static initialize(app) {
        this.clear();
        this._setupEventHandlers(app);
    }

    static clear() {
        this._mousePressed = false;
        this._screenPressed = false;
        this._pressedTime = 0;
        this._events = {};
        this._events.triggered = false;
        this._events.cancelled = false;
        this._events.moved = false;
        this._events.released = false;
        this._events.wheelX = 0;
        this._events.wheelY = 0;
        this._triggered = false;
        this._cancelled = false;
        this._moved = false;
        this._released = false;
        this._wheelX = 0;
        this._wheelY = 0;
        this._x = 0;
        this._y = 0;
        this._date = 0;
    }

    static update() {
        this._triggered = this._events.triggered;
        this._cancelled = this._events.cancelled;
        this._moved = this._events.moved;
        this._released = this._events.released;
        this._wheelX = this._events.wheelX;
        this._wheelY = this._events.wheelY;
        this._events.triggered = false;
        this._events.cancelled = false;
        this._events.moved = false;
        this._events.released = false;
        this._events.wheelX = 0;
        this._events.wheelY = 0;
        if (this.isPressed()) {
            this._pressedTime++;
        }
    }

    static isPressed() {
        return this._mousePressed || this._screenPressed;
    }

    static isTriggered() {
        return this._triggered;
    }

    static isRepeated() {
        return (this.isPressed() &&
            (this._triggered ||
                (this._pressedTime >= this.keyRepeatWait &&
                    this._pressedTime % this.keyRepeatInterval === 0)));
    }

    static isLongPressed() {
        return this.isPressed() && this._pressedTime >= this.keyRepeatWait;
    }

    static isCancelled() {
        return this._cancelled;
    }

    static isMoved() {
        return this._moved;
    }

    static isReleased() {
        return this._released;
    }

    static get wheelX() {
        return this._wheelX;
    }

    static get wheelY() {
        return this._wheelY;
    }

    static get x() {
        return this._x;
    }

    static get y() {
        return this._y;
    }

    static get date() {
        return this._date;
    }

    static _setupEventHandlers(app) {
        app.stage.on('pointerdown', this._onPointerDown);
        app.stage.on('pointerup',this._onPointerUp);
        app.stage.on('pointercancel', this._onPointerCancel);
        app.stage.on('pointermove', this._onPointerMove);
        app.stage.on('wheel', this._onWheel);
    }

     static _onPointerCancel=(event)=> {
        this._screenPressed = false;
    }

    static _onPointerDown = (event) => {
        switch (event.pointerType) {
            case 'mouse':
                this._onMouseDown(event); break;
            case 'touch':
                this._onTouchStart(event); break;
            default:
                break;
        }

    }

    static _onPointerMove=(event)=> {
        switch (event.pointerType) {
            case 'mouse':
                this._onMouseMove(event); break;
            case 'touch':
                this._onTouchMove(event); break;
            default:
                break;
        }
       
    }

    static _onPointerUp=(event)=>{
        switch(event.pointerType){
            case 'mouse':
                this._onMouseUp(event);break;
            case 'touch':
                this._onTouchEnd(event);break;
        }
    }

    static _onWheel=(event)=> {
        this._events.wheelX += event.deltaX;
        this._events.wheelY += event.deltaY;
        event.preventDefault();
    }

    static _onMouseDown(event){
        if (event.button === 0) {
            this._onLeftButtonDown(event);
        } else if (event.button === 1) {
            this._onMiddleButtonDown(event);
        } else if (event.button === 2) {
            this._onRightButtonDown(event);
        }
    }

    static _onMouseUp(event){
        if (event.button === 0) {
            this._mousePressed = false;
            this._onRelease(event.global.x, event.global.y);
        }
    }

    static _onMouseMove(event) {
        if (this._mousePressed) {
            let x = event.global.x;
            let y = event.global.y;
            this._onMove(x, y);
        }
    }

    static _onLeftButtonDown(event) {
        this._mousePressed = true;
        this._pressedTime = 0;
        this._onTrigger(event.global.x, event.global.y);
    }

    static _onMiddleButtonDown(event) {}

    static _onRightButtonDown(event) {
        this._onCancel(event.global.x, event.global.y);
    }

    static _onTouchStart(event) {
        let x = event.global.x;
        let y = event.global.y;

        this._screenPressed = true;
        this._pressedTime = 0;

        if (event.pointerId >= 2) {
            this._onCancel(x, y);
        } else {
            this._onTrigger(x, y);
        }

        event.preventDefault();
    }

    static _onTouchMove(event){
        let x = event.global.x;
        let y = event.global.y;
        this._onMove(x, y);
    }

    static _onTouchEnd(event) {

        this._screenPressed = false;
        this._onRelease(event.global.x, event.global.y);
    }

    static _onTrigger(x, y) {
        this._events.triggered = true;
        this._x = x;
        this._y = y;
        this._date = Date.now();
    }

    static _onCancel(x, y) {
        this._events.cancelled = true;
        this._x = x;
        this._y = y;
    }

    static _onMove(x, y) {
        this._events.moved = true;
        this._x = x;
        this._y = y;
    }

    static _onRelease(x, y) {
        this._events.released = true;
        this._x = x;
        this._y = y;
    }
}

